package com.zhucai.credit.service.impl.transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.zhucai.credit.bean.CreditApplication;
import com.zhucai.credit.bean.CreditRecord;
import com.zhucai.credit.bean.CreditRecordTime;
import com.zhucai.credit.bean.FinanceDraw;
import com.zhucai.credit.bean.FinanceRepayment;
import com.zhucai.credit.bean.PaymentOrderItem;
import com.zhucai.credit.common.CommonEnums.CreditStatus;
import com.zhucai.credit.common.EnumHelper;
import com.zhucai.credit.common.HelpConstant;
import com.zhucai.credit.model.CreditApplicationEntity;
import com.zhucai.credit.model.CreditProductEntity;
import com.zhucai.credit.model.CreditRecordEntrity;
import com.zhucai.credit.model.CreditRecordTimeEntrity;
import com.zhucai.credit.model.PaymentOrderItemEntity;
import com.zhucai.credit.repository.CreditApplicationRepository;
import com.zhucai.credit.repository.CreditProductRepository;
import com.zhucai.credit.repository.CreditRecordRepository;
import com.zhucai.credit.repository.CreditRecordTimeRepository;
import com.zhucai.credit.repository.EntCrProdEntityRepository;
import com.zhucai.credit.repository.FinanceDrawRepository;
import com.zhucai.credit.repository.FinanceRepaymentRepository;
import com.zhucai.credit.repository.PaymentOrderItemRepository;
import com.zhucai.credit.service.impl.problem.ProblemSericeImpl;
import com.zhucai.credit.utils.SqlResultUtil;
import com.zhucai.credit.utils.TimeUtils;

@Service
public class CreditUserServiceUtil {
	private static final Logger logger = LoggerFactory.getLogger(CreditUserServiceUtil.class);
	@Autowired
	private CreditRecordRepository creditRecordRepository;
	@Autowired
	private EntCrProdEntityRepository entCrProdEntityRepository;
	@Autowired
	private FinanceDrawRepository financeDrawRepository;
	@Autowired
	private FinanceRepaymentRepository financeRepaymentRepository;
	@Autowired
	private CreditRecordTimeRepository creditRecordTimeRepository;
	@Autowired
	private ProblemSericeImpl problemSericeImpl;
	@Autowired
	private CreditUserServiceUtil creditUserServiceUtil;
	@Autowired
	private PaymentOrderItemRepository paymentOrderItemRepository;
	@Autowired
	private CreditProductRepository creditProductRepository;
	@Autowired
	private CreditApplicationRepository creditApplicationRepository;

	/**
	 * 查询融资信息公共方法
	 * 
	 * @author hsg
	 * @version 2018年7月13日
	 * @param payId
	 * @param tid
	 * @return
	 */
	public CreditRecord findCreditRecordInfo(Long payId, Long tid) {
		logger.info("### 查询融资信息公共方法(findCreditRecordInfo) start,参数payId={},参数tid={}", payId, tid);
		CreditRecord cr = new CreditRecord();
		try {
			List<Object[]> findByTidAndPaymentId = creditRecordRepository.findByTidAndPaymentId(HelpConstant.Status.delete, payId, tid);
			if (CollectionUtils.isEmpty(findByTidAndPaymentId)) {
				return null;
			}
			for (Object[] object : findByTidAndPaymentId) {
				cr.setTid(SqlResultUtil.getSqlResultLong(object[0]));
				cr.setRecordNo(SqlResultUtil.getSqlResultString(object[1]));
				cr.setOriginatorUserId(SqlResultUtil.getSqlResultLong(object[2]));
				cr.setOriginator(SqlResultUtil.getSqlResultLong(object[3]));
				cr.setParticipator(SqlResultUtil.getSqlResultLong(object[4]));
				cr.setParticipatorUserId(SqlResultUtil.getSqlResultLong(object[5]));
				cr.setCrProdId(SqlResultUtil.getSqlResultLong(object[6]));
				cr.setPaymentNum(SqlResultUtil.getSqlResultString(object[7]));
				cr.setPaymentId(SqlResultUtil.getSqlResultLong(object[8]));
				cr.setContractId(SqlResultUtil.getSqlResultLong(object[9]));
				cr.setContractNum(SqlResultUtil.getSqlResultString(object[10]));
				cr.setContractNumCcb(SqlResultUtil.getSqlResultString(object[11]));
				cr.setInvoiceNoCode(SqlResultUtil.getSqlResultString(object[12]));
				cr.setCreditStatus(SqlResultUtil.getSqlResultString(object[13]));
				cr.setCreditUnusualStatus(SqlResultUtil.getSqlResultString(object[14]));
				cr.setRejectReason(SqlResultUtil.getSqlResultString(object[15]));
				cr.setCreditAmount(SqlResultUtil.getSqlResultBigDecimal(object[16]));
				cr.setCreditGetAmount(SqlResultUtil.getSqlResultBigDecimal(object[17]));
				cr.setLoanDate(SqlResultUtil.getSqlResultDate2(SqlResultUtil.getSqlResultString(object[18])));
				cr.setLoanDateCcb(SqlResultUtil.getSqlResultDate2(SqlResultUtil.getSqlResultString(object[19])));
				cr.setRepaymentAmount(SqlResultUtil.getSqlResultBigDecimal(object[20]));
				cr.setPurRepaymentAmount(SqlResultUtil.getSqlResultBigDecimal(object[21]));
				cr.setSupRepaymentAmount(SqlResultUtil.getSqlResultBigDecimal(object[22]));
				cr.setDrawAmount(SqlResultUtil.getSqlResultBigDecimal(object[23]));
				cr.setDrawRate(SqlResultUtil.getSqlResultBigDecimal(object[24]));
				cr.setTransactionTime(SqlResultUtil.getSqlResultDate2(SqlResultUtil.getSqlResultString(object[25])));
				cr.setInvoiceTid(SqlResultUtil.getSqlResultLong(object[26]));
				cr.setProjectTid(SqlResultUtil.getSqlResultLong(object[27]));
				cr.setAppNum(SqlResultUtil.getSqlResultString(object[28]));
				cr.setPurEnteriseName(SqlResultUtil.getSqlResultString(object[29]));
				cr.setSupEnteriseName(SqlResultUtil.getSqlResultString(object[30]));
				cr.setProjectName(SqlResultUtil.getSqlResultString(object[31]));
				cr.setInvoiceFileName(SqlResultUtil.getSqlResultString(object[32]));
				cr.setInvoiceNo(SqlResultUtil.getSqlResultString(object[33]));
				cr.setInvoiceCode(SqlResultUtil.getSqlResultString(object[34]));
				if (object[35] != null) {
					cr.setInvoiceAmount(SqlResultUtil.getSqlResultBigDecimal(object[35]));
				}
				cr.setInvoiceDate(SqlResultUtil.getSqlResultDate2(SqlResultUtil.getSqlResultString(object[36])));
				cr.setCrProdBankName(SqlResultUtil.getSqlResultString(object[37]));
				cr.setInvoiceFileId(SqlResultUtil.getSqlResultLong(object[38]));
				//账款到期天数
				Integer dateTian = TimeUtils.dateTian(cr.getLoanDate(), new Date());
				cr.setCreditPeriod(dateTian);
				//距离还款天数
				if(cr.getLoanDateCcb()!=null){
					Integer fromRepaymentDate = TimeUtils.dateTian(cr.getLoanDateCcb(), new Date());
					cr.setFromRepaymentDate(fromRepaymentDate);
				}
				// 融资利率
				BigDecimal crProdRate = SqlResultUtil.getSqlResultBigDecimal(object[39]);
				BigDecimal orderAmt = SqlResultUtil.getOrderAmt(cr.getCreditGetAmount(), dateTian, crProdRate).setScale(2, BigDecimal.ROUND_HALF_UP);
				cr.setOrderAmt(orderAmt);
				// 查询是否有线下支付正在发生
				List<PaymentOrderItem> paymentOrderItemList = new ArrayList<PaymentOrderItem>();
				List<PaymentOrderItemEntity> paymentOrderItemEntList = paymentOrderItemRepository.findOfflineItemInfo(cr.getRecordNo());
				if (CollectionUtils.isNotEmpty(paymentOrderItemEntList)) {
					for (PaymentOrderItemEntity paymentOrderItemEntity : paymentOrderItemEntList) {
						PaymentOrderItem paymentOrderItem = new PaymentOrderItem();
						BeanUtils.copyProperties(paymentOrderItemEntity, paymentOrderItem);
						paymentOrderItemList.add(paymentOrderItem);
						cr.setPaymentOrderItemList(paymentOrderItemList);
					}
				}
				// 判断是否有支付完成的正常的支付明细
				Integer paySuccessCount = paymentOrderItemRepository.findByStatusNotAndOrderNoAndNormal(HelpConstant.Status.delete, cr.getRecordNo(), "NORMAL");
				if (paySuccessCount > 0) {
					cr.setPayState(true);
				} else {
					cr.setPayState(false);
				}

			}

			// 查询融资历时记录
			List<CreditRecordTime> crtList = new ArrayList<CreditRecordTime>();
			List<CreditRecordTimeEntrity> findByCrRecordIdAndRecordStatus = creditRecordTimeRepository.findByCrRecordId(cr.getTid());
			if (CollectionUtils.isNotEmpty(findByCrRecordIdAndRecordStatus)) {
				for (CreditRecordTimeEntrity creditRecordTimeEntrity : findByCrRecordIdAndRecordStatus) {
					CreditRecordTime creditRecordTime = new CreditRecordTime();
					BeanUtils.copyProperties(creditRecordTimeEntrity, creditRecordTime);
					crtList.add(creditRecordTime);
				}
			}
			cr.setCreditRecordTimeList(crtList);

			// 获取等待时间
			String waitTime = "已等待" + getWaitTime(cr.getTid());
			cr.setWaitTime(waitTime);

			// 查询融资记录关联银行的信息
			CreditProductEntity creditProductEntity = creditProductRepository.findByTidAndStatusNot(cr.getCrProdId(), HelpConstant.Status.delete);
			if (creditProductEntity != null) {
				cr.setContractUrlAddress(creditProductEntity.getContractUrlAddress());
				cr.setDrawUrlAddress(creditProductEntity.getDrawUrlAddress());
			}
			List<FinanceDraw> drawList = getDrawList(cr.getTid());
			if (CollectionUtils.isNotEmpty(drawList)) {
				cr.setDrawList(drawList);
			}
			List<FinanceRepayment> repaymentList = getRepaymentList(cr.getTid());
			if (CollectionUtils.isNotEmpty(repaymentList)) {
				cr.setRepaymentList(repaymentList);
			}
		} catch (Exception e) {
			logger.error("### 根据计划付款id查询融资记录(findCreditRecordByPayiId)发生异常，errMsg={}", e);
			return null;
		}
		return cr;

	}

	/**
	 * 获取等待时间
	 * 
	 * @version 2018年8月3日
	 * @param recordTid
	 * @return
	 */
	public String getWaitTime(Long recordId) {
		logger.info("### 获取等待时间 start tid={}", recordId);
		CreditRecordEntrity cre = creditRecordRepository.findOne(recordId);
		if (cre == null) {
			return null;
		}
		String waitTime = null;
		List<CreditRecordTimeEntrity> findRecordTimeInfo = creditRecordTimeRepository.findRecordTimeInfo(recordId);
		if (CollectionUtils.isNotEmpty(findRecordTimeInfo)) {
			waitTime = TimeUtils.dateDiff(new Date(), findRecordTimeInfo.get(0).getRecordingTime());

		}

		return waitTime;

	}

	// 根据融资id查询支取记录
	public List<FinanceDraw> getDrawList(Long recordTid) {

		List<Object[]> draw = financeDrawRepository.findByStatusNotAndOutId(HelpConstant.Status.delete, recordTid);

		List<FinanceDraw> drawList = new ArrayList<FinanceDraw>();
		if (CollectionUtils.isNotEmpty(draw)) {
			for (Object[] obj : draw) {
				FinanceDraw fd = new FinanceDraw();
				fd.setTid(SqlResultUtil.getSqlResultLong(obj[0]));
				fd.setEnterpriseName(SqlResultUtil.getSqlResultString(obj[1]));
				fd.setDrawTime(SqlResultUtil.getSqlResultDate2(SqlResultUtil.getSqlResultString(obj[2])));
				fd.setDrawAmount(SqlResultUtil.getSqlResultBigDecimal(obj[3]));
				drawList.add(fd);
			}
		}

		return drawList;
	}

	// 根据融资id查询还款记录
	public List<FinanceRepayment> getRepaymentList(Long recordTid) {

		// 获取还款记录
		List<Object[]> repayment = financeRepaymentRepository.findByStatusNotAndOutId(HelpConstant.Status.delete, recordTid);

		List<FinanceRepayment> repaymentList = new ArrayList<FinanceRepayment>();

		if (CollectionUtils.isNotEmpty(repayment)) {
			for (Object[] obj : repayment) {
				FinanceRepayment fr = new FinanceRepayment();
				fr.setTid(SqlResultUtil.getSqlResultLong(obj[0]));
				fr.setEnterpriseName(SqlResultUtil.getSqlResultString(obj[1]));
				fr.setPaymentTime(SqlResultUtil.getSqlResultDate2(SqlResultUtil.getSqlResultString(obj[2])));
				fr.setPaymentAmount(SqlResultUtil.getSqlResultBigDecimal(obj[3]));
				repaymentList.add(fr);
			}
		}
		return repaymentList;
	}

	// 操作CreditRecordTimeRepository
	public CreditRecordTimeEntrity createRecordTime(Long recordId, String recordStatus) {
		try {
			// 判断是否是从发起开始
			if (CreditStatus.WAIT_SUBMIT.toString().equals(recordStatus)) {
				// 查询融资记录历史是否为空
				List<CreditRecordTimeEntrity> creditRecordTimeList = creditRecordTimeRepository.findByCrRecordIdAndStatusNot(recordId, HelpConstant.Status.delete);
				// 删除
				if (CollectionUtils.isNotEmpty(creditRecordTimeList)) {
					Integer coo = creditRecordTimeRepository.deleteRecordTimeByRecordId(recordId);
					if (creditRecordTimeList.size() != coo) {
						String problem = "逻辑删除CreditRecordTimeEntrity时删除的记录和查询的条数不一致，查询List<CreditRecordTimeEntrity>的集合条数为" + creditRecordTimeList.size() + "，逻辑删除的条数是coo" + coo;
						problemSericeImpl.setProblem(problem, "createRecordTime");
					}
				}
			}
			// 查询是否存在重复
			List<CreditRecordTimeEntrity> findByCrRecordIdAndType = creditRecordTimeRepository.findByCrRecordIdAndType(recordId, recordStatus);
			// 新增CreditRecordTimeEntrity
			CreditRecordTimeEntrity creditRecordTimeEntrity = new CreditRecordTimeEntrity();
			if (CollectionUtils.isNotEmpty(findByCrRecordIdAndType)) {
				creditRecordTimeEntrity = findByCrRecordIdAndType.get(0);
				creditRecordTimeEntrity.setModifyDescription(creditRecordTimeEntrity.getModifyDescription() + "+1");
				if (recordStatus.equals(CreditStatus.REPAYMENT.toString())) {
					creditRecordTimeEntrity.setRecordingTime(new Date());
				}
			} else {
				creditRecordTimeEntrity.setCrRecordId(recordId);
				creditRecordTimeEntrity.setRecordingType(recordStatus);
				creditRecordTimeEntrity.setRecordingTime(new Date());
				creditRecordTimeEntrity.setRecordingRemark(EnumHelper.getDescribe(CreditStatus.valueOf(recordStatus)));
				creditRecordTimeEntrity.setModifyDescription(EnumHelper.getDescribe(CreditStatus.valueOf(recordStatus)));
				// 判断在那个阶段
				if (CreditStatus.WAIT_CONFIRM_ZZW.toString().equals(recordStatus)) {
					// 查询离筑材网审核最近的发起时间
					List<CreditRecordTimeEntrity> findByCrRecordIdAndRecordStatus = creditRecordTimeRepository.findByCrRecordIdAndRecordStatus(recordId,
							CreditStatus.WAIT_SUBMIT.toString());
					if (CollectionUtils.isNotEmpty(findByCrRecordIdAndRecordStatus)) {
						String timeBetween = TimeUtils.dateDiff(findByCrRecordIdAndRecordStatus.get(0).getRecordingTime(), new Date());
						creditRecordTimeEntrity.setRecordingBetween(timeBetween);
					}

				} else if (CreditStatus.WAIT_CONFIRM.toString().equals(recordStatus)) {
					// 查询筑材网的审核时间
					List<CreditRecordTimeEntrity> findByCrRecordIdAndRecordStatus = creditRecordTimeRepository.findByCrRecordIdAndRecordStatus(recordId,
							CreditStatus.WAIT_CONFIRM_ZZW.toString());
					if (CollectionUtils.isNotEmpty(findByCrRecordIdAndRecordStatus)) {
						String timeBetween = TimeUtils.dateDiff(findByCrRecordIdAndRecordStatus.get(0).getRecordingTime(), new Date());
						creditRecordTimeEntrity.setRecordingBetween(timeBetween);
					}
				} else if (CreditStatus.WAIT_PAY.toString().equals(recordStatus)) {
					// 查询供应商确认时间
					List<CreditRecordTimeEntrity> findByCrRecordIdAndRecordStatus = creditRecordTimeRepository.findByCrRecordIdAndRecordStatus(recordId,
							CreditStatus.WAIT_CONFIRM.toString());
					if (CollectionUtils.isNotEmpty(findByCrRecordIdAndRecordStatus)) {
						String timeBetween = TimeUtils.dateDiff(findByCrRecordIdAndRecordStatus.get(0).getRecordingTime(), new Date());
						creditRecordTimeEntrity.setRecordingBetween(timeBetween);
					}
				} else if (CreditStatus.SUBSTITUTE_CONTRACT.toString().equals(recordStatus)) {
					// 查询发起成功的时间算总历时
					List<CreditRecordTimeEntrity> findByCrRecordIdAndRecordStatus = creditRecordTimeRepository.findByCrRecordIdAndRecordStatus(recordId,
							CreditStatus.WAIT_SUBMIT.toString());
					if (CollectionUtils.isNotEmpty(findByCrRecordIdAndRecordStatus)) {
						// 总历时
						String allTimeBetween = TimeUtils.dateDiff(findByCrRecordIdAndRecordStatus.get(0).getRecordingTime(), new Date());
						creditRecordTimeEntrity.setRecordingAllBetween(allTimeBetween);
					}
					// 查询支付成功的时间算单个历时
					List<CreditRecordTimeEntrity> creditRecordTimeList = creditRecordTimeRepository.findByCrRecordIdAndRecordStatus(recordId, CreditStatus.WAIT_PAY.toString());
					if (CollectionUtils.isNotEmpty(creditRecordTimeList)) {
						// 单个历时
						String timeBetween = TimeUtils.dateDiff(creditRecordTimeList.get(0).getRecordingTime(), new Date());
						creditRecordTimeEntrity.setRecordingBetween(timeBetween);
					}
				} else if (CreditStatus.PENDING_WITHDRAWAL.toString().equals(recordStatus)) {
					// 查询签合同的时间
					List<CreditRecordTimeEntrity> findByCrRecordIdAndRecordStatus = creditRecordTimeRepository.findByCrRecordIdAndRecordStatus(recordId,
							CreditStatus.SUBSTITUTE_CONTRACT.toString());
					if (CollectionUtils.isNotEmpty(findByCrRecordIdAndRecordStatus)) {
						String timeBetween = TimeUtils.dateDiff(findByCrRecordIdAndRecordStatus.get(0).getRecordingTime(), new Date());
						creditRecordTimeEntrity.setRecordingBetween(timeBetween);
					}
				} else if (CreditStatus.REPAYMENT.toString().equals(recordStatus)) {
					// 查询支取的时间
					List<CreditRecordTimeEntrity> findByCrRecordIdAndRecordStatus = creditRecordTimeRepository.findByCrRecordIdAndRecordStatus(recordId,
							CreditStatus.PENDING_WITHDRAWAL.toString());
					if (CollectionUtils.isNotEmpty(findByCrRecordIdAndRecordStatus)) {
						String timeBetween = TimeUtils.dateDiff(findByCrRecordIdAndRecordStatus.get(0).getRecordingTime(), new Date());
						creditRecordTimeEntrity.setRecordingBetween(timeBetween);
						creditRecordTimeEntrity.setRecordingTime(new Date());
					}
				}
			}
			creditRecordTimeRepository.save(creditRecordTimeEntrity);
		} catch (Exception e) {
			// TODO: handle exception
			String problem = "新增历时记录时发生异常，recordId =" + recordId;
			problemSericeImpl.setProblem(problem, "findByCrRecordIdAndRecordStatus");

			logger.error("### 新增历时记录时发生异常，recordId ={}，errMsh={}", recordId, e);
		}
		return null;

	}
	
	/**
	 * 查询融资资质申请信息公共方法
	 */
	
	public CreditApplication getCreditApplicationById(Long tid){
		
		CreditApplicationEntity cae = creditApplicationRepository.findOne(tid);
		
		if(cae == null ){
			return null;
		}
		CreditApplication ca = new CreditApplication();
		BeanUtils.copyProperties(cae, ca);
		//查询相关的企业信息
		List<Object[]> rs = creditApplicationRepository.findEntInfoById(tid);
		if(CollectionUtils.isNotEmpty(rs)){
			for (Object[] obj : rs) {
				ca.setEnterpriseSupName(SqlResultUtil.getSqlResultString(obj[0]));
				if(SqlResultUtil.getSqlResultString(obj[6]) == null ||  SqlResultUtil.getSqlResultString(obj[6]).equals("")){
					ca.setLinkPerson(SqlResultUtil.getSqlResultString(obj[1]));
				}else{
					ca.setLinkPerson(SqlResultUtil.getSqlResultString(obj[6]));
				}
				if(SqlResultUtil.getSqlResultString(obj[7]) == null ||  SqlResultUtil.getSqlResultString(obj[7]).equals("")){
					ca.setLinkTel(SqlResultUtil.getSqlResultString(obj[2]));
				}else{
					ca.setLinkTel(SqlResultUtil.getSqlResultString(obj[7]));
				}
				ca.setEnterprisePurName(SqlResultUtil.getSqlResultString(obj[3]));
				ca.setBusBankName(SqlResultUtil.getSqlResultString(obj[4]));
				ca.setCrProdType(SqlResultUtil.getSqlResultString(obj[5]));
			}
		}
		return ca;
		
	}
}